﻿Imports System.ComponentModel
Imports System.Runtime.InteropServices
Imports System.Threading

Public Class Form3
	Public Property HwID As String = Nothing
	Private ResetEvent As New AutoResetEvent(False)	' kvuli pockani na BackgroundWorker.CancelAsync(), protoze to chvili trva nez nastavi promennou, ktera se pak cte a jeji obsah neodpovida

	Private Sub Form3_Shown(sender As Object, e As EventArgs) Handles MyBase.Shown
		PustSledovaniKlavesnice()
	End Sub

	Private Sub Form3_Load(sender As Object, e As EventArgs) Handles MyBase.Load
		If dictCodeKey.Count = 0 Then
			InicializujSlovniky()
		End If
	End Sub

	Private Sub BackgroundWorker1_DoWork(sender As Object, e As System.ComponentModel.DoWorkEventArgs) Handles BackgroundWorker1.DoWork
		'MsgBox("zacatek")
		Dim BW As BackgroundWorker = CType(sender, BackgroundWorker)
		KeyTest3(BW)
	End Sub

	Private Sub BackgroundWorker1_RunWorkerCompleted(sender As Object, e As System.ComponentModel.RunWorkerCompletedEventArgs) Handles BackgroundWorker1.RunWorkerCompleted
		'MsgBox("konec")
		Me.Close()
	End Sub

	Sub PustSledovaniKlavesnice()
		If Not BackgroundWorker1.IsBusy Then
			BackgroundWorker1.RunWorkerAsync()
		End If
	End Sub

	Sub ZastavSledovaniKlavesnice()
		If BackgroundWorker1.IsBusy Then
			BackgroundWorker1.CancelAsync()
			ResetEvent.WaitOne()
		End If
	End Sub

	Private Sub KeyTest3(BW As BackgroundWorker)
		Dim hDll As IntPtr = LoadLibrary("interception.dll")
		Dim pointer_interception_is_keyboard As IntPtr = GetProcAddress(hDll, "interception_is_keyboard")
		Dim pointer_interception_is_mouse As IntPtr = GetProcAddress(hDll, "interception_is_mouse")

		Dim context As IntPtr
		Dim device As System.Int32

		' vytvor context
		context = InterceptionWrapper.interception_create_context
		' nastav filtry
		Dim MyFilter As System.UInt16 = InterceptionFilterKeyState.INTERCEPTION_FILTER_KEY_DOWN Or InterceptionFilterKeyState.INTERCEPTION_FILTER_KEY_E0 Or InterceptionFilterKeyState.INTERCEPTION_FILTER_KEY_UP
		InterceptionWrapper.interception_set_filter(context, pointer_interception_is_keyboard, MyFilter)

		'''''''' alokovani UNmanaged promennych v pameti a vytvoreni pointeru na ne
		' vseobsazny STROKE, je dan velikosti mouse stroke, protoze je vetsi nez key stroke
		Dim AllStroke As InterceptionMouseStroke
		Dim pAllStroke As IntPtr = Marshal.AllocHGlobal(Marshal.SizeOf(AllStroke))
		Marshal.StructureToPtr(AllStroke, pAllStroke, False)
		' mouse stroke
		Dim MouseStroke As InterceptionMouseStroke
		Dim pMouseStroke As IntPtr = Marshal.AllocHGlobal(Marshal.SizeOf(MouseStroke))
		Marshal.StructureToPtr(MouseStroke, pMouseStroke, False)
		' key stroke
		Dim KeyStrokeProPamet As InterceptionKeyStroke
		Dim pKeyStroke As IntPtr = Marshal.AllocHGlobal(Marshal.SizeOf(KeyStrokeProPamet))
		Marshal.StructureToPtr(KeyStrokeProPamet, pKeyStroke, False)

		Const HardwareIDbufferSize = 2000
		Dim pHardwareID As IntPtr = Marshal.AllocHGlobal(HardwareIDbufferSize)

		Do
			If BW.CancellationPending Then
				Exit Do
			End If

			' zarizeni na kterem byla akce
			device = InterceptionWrapper.interception_wait_with_timeout(context, 1)
			' co se zmacklo
			Dim receive As System.Int32 = InterceptionWrapper.interception_receive(context, device, pAllStroke, 1)
			If receive = 0 Then Continue Do

			' zarizeni je klavesnice
			If InterceptionWrapper.interception_is_keyboard(device) Then
				Dim HardwareIDLength As System.Int32 = InterceptionWrapper.interception_get_hardware_id(context, device, pHardwareID, HardwareIDbufferSize)
				HwID = Nothing
				If HardwareIDLength > 0 And HardwareIDLength < HardwareIDbufferSize Then
					HwID = Marshal.PtrToStringAuto(pHardwareID)
					Exit Do
				End If
			End If
		Loop

		InterceptionWrapper.interception_destroy_context(context)

		' uvolneni unmanaged promennych
		Marshal.FreeHGlobal(pAllStroke)
		Marshal.FreeHGlobal(pMouseStroke)
		Marshal.FreeHGlobal(pKeyStroke)

		FreeLibrary(hDll)

		If BW.CancellationPending Then
			ResetEvent.Set()
		End If
	End Sub

	Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
		ZastavSledovaniKlavesnice()
	End Sub
End Class